home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / PGM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-21  |  5.9 KB  |  206 lines

  1. /****************************************************************************
  2. *                pgm.c
  3. *
  4. *  This module contains the code to read the PGM file format.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. * Original patch copyright 1994 Tim Rowley
  23. * Updated for POV 3.0 by Chris Cason, Jan '95.
  24. *
  25. *****************************************************************************/
  26.  
  27. /****************************************************************************
  28. *  The format is as follows:
  29. *
  30. *  (header:)
  31. *    P2              - ASCII data in file OR
  32. *    P5              - binary data in file
  33. *    # hello         - comment (optional, may be multiple)
  34. *    wwww hhhh       - Width, Height (ASCII text)
  35. *    # world         - comment (optional, may be multiple)
  36. *    nnn             - maximum color (nnn = white, 0 = black)
  37. *
  38. *  (each pixel: one of the following)
  39. *    xx               - Intensity 0-nnn (binary byte)
  40. *    AAA              - Intensity 0-nnn (ASCII number)
  41. *
  42. *****************************************************************************/
  43.  
  44. #include "frame.h"
  45. #include "povproto.h"
  46. #include "povray.h"
  47. #include "pgm.h"
  48. #include "ppm.h"
  49.  
  50. /*****************************************************************************
  51. *
  52. * FUNCTION
  53. *
  54. *  Read_PGM_Image
  55. *
  56. * INPUT
  57. *   
  58. * OUTPUT
  59. *   
  60. * RETURNS
  61. *   
  62. * AUTHOR
  63. *   
  64. * DESCRIPTION
  65. *
  66. * CHANGES
  67. *     Modified to support ASCII files, comments, and arbitrary bit depth [AED]
  68. *
  69. ******************************************************************************/
  70.  
  71. void Read_PGM_Image(Image, name)
  72. IMAGE *Image;
  73. char *name;
  74. {
  75.   char type;
  76.   int width, height;
  77.   int depth;
  78.   char input;
  79.   char junk[512];
  80.   int x, y;
  81.   int data;
  82.   FILE *infile;
  83.  
  84.   if ((infile = Locate_File(name,READ_FILE_STRING,".pgm",".PGM",TRUE)) == NULL)
  85.   {
  86.     Error ("Cannot open PGM image %s.\n", name);
  87.   }
  88.  
  89.   if (fscanf(infile,"P%c\n",&type) != 1 || (type != '2' && type != '5'))
  90.   {
  91.     Error ("File is not in PGM format.\n");
  92.   }
  93.  
  94.   /* Ignore any comments */
  95.   while ((input = fgetc(infile)) == '#')
  96.   {
  97.     fgets(junk,512,infile);
  98.   }
  99.  
  100.   ungetc(input,infile);
  101.  
  102.   if (fscanf(infile,"%d %d\n",&width,&height) != 2)
  103.   {
  104.     Error ("Error reading width or height from PGM image.\n");
  105.   }
  106.  
  107.   /* Ignore any comments */
  108.   while ((input = fgetc(infile)) == '#')
  109.   {
  110.     fgets(junk,512,infile);
  111.   }
  112.  
  113.   ungetc(input,infile);
  114.  
  115.   if (fscanf(infile,"%d\n",&depth) != 1 ||
  116.       (depth > 255 && type == '5') ||
  117.       depth > 65535 || depth < 1)
  118.   {
  119.     Error ("Unsupported number of colors (%d) in PGM image.\n", depth);
  120.   }
  121.  
  122.  
  123.   Image->width  = (DBL)(Image->iwidth  = width);
  124.   Image->height = (DBL)(Image->iheight = height);
  125.  
  126.   if (depth < 256)
  127.   {
  128.     Image->Colour_Map_Size = depth;
  129.  
  130.     Image->Colour_Map = (IMAGE_COLOUR *)POV_MALLOC(depth*sizeof(IMAGE_COLOUR), "PGM color map");
  131.  
  132.     for (x = 0; x < depth; x++)
  133.     {
  134.       Image->Colour_Map[x].Red =
  135.       Image->Colour_Map[x].Green =
  136.       Image->Colour_Map[x].Blue = x*255/depth;
  137.       Image->Colour_Map[x].Filter =0;
  138.       Image->Colour_Map[x].Transmit =0;
  139.     }
  140.  
  141.     Image->data.map_lines = (unsigned char **)POV_MALLOC(height*sizeof(unsigned char *), "PGM image");
  142.  
  143.     for (y = 0; y < height; y++)
  144.     {
  145.       Image->data.map_lines[y] = (unsigned char *)POV_MALLOC(width,"PGM image line");
  146.  
  147.       if (type == '2') /* ASCII data to be input */
  148.       {
  149.         for (x = 0; x < width; x++)
  150.         {
  151.           if (fscanf(infile,"%d",&data) != 1)
  152.           {
  153.             Error ("Error reading data from PGM image.\n");
  154.           }
  155.           Image->data.map_lines[y][x] = data;
  156.         }
  157.       }
  158.       else /* (type == '5') Raw binary data to be input */
  159.       {
  160.         for (x = 0; x < width; x++)
  161.         {
  162.           if ((data = getc(infile)) == EOF)
  163.           {
  164.             Error ("Error reading data from PGM image.\n");
  165.           }
  166.           Image->data.map_lines[y][x] = data;
  167.         }
  168.       }
  169.     }
  170.   }
  171.   else /* if(depth < 65536) the data MUST be in ASCII format */
  172.   {
  173.     IMAGE_LINE *line_data;
  174.  
  175.     Image->Colour_Map_Size = 0;
  176.     Image->Colour_Map = (IMAGE_COLOUR *)NULL;
  177.  
  178.     Image->data.rgb_lines = (IMAGE_LINE *)POV_MALLOC(height * sizeof(IMAGE_LINE), "PGM image");
  179.     for (y = 0; y < height; y++)
  180.     {
  181.       line_data = &Image->data.rgb_lines[y];
  182.  
  183.       line_data->red   = (unsigned char *)POV_MALLOC(width, "PGM image line");
  184.       line_data->green = (unsigned char *)POV_MALLOC(width, "PGM image line");
  185.       line_data->blue  = (unsigned char *)POV_MALLOC(width, "PGM image line");
  186.       line_data->transm = (unsigned char *)NULL;
  187.  
  188.       for (x = 0; x < width; x++)
  189.       {
  190.         if (fscanf(infile,"%d",&data) != 1)
  191.         {
  192.           Error("Error reading data from PGM image.\n");
  193.         }
  194.  
  195.         data = (int)((DBL)data*65535/depth);
  196.  
  197.         line_data->red[x] = (data >> 8) & 0xFF;
  198.         line_data->green[x] = data & 0xFF;
  199.         line_data->blue[x] = 0;
  200.       }
  201.     }
  202.   }
  203.  
  204.   fclose(infile);
  205. }
  206.